package com.example.register1.service.impl;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.example.register1.Dto.PageDTO;
import com.example.register1.domin.BookIndex;
import com.example.register1.domin.Register;
import com.example.register1.mapper.IndexMapper;
import com.example.register1.mapper.RegisterMapper;
import com.example.register1.result.PageResult;
import com.example.register1.result.Result;
import com.example.register1.service.RegisterService;
import com.example.register1.vo.BooksAndNamesVO;
import com.example.register1.vo.BooksVO;
import com.example.register1.vo.NamesVO;
import com.example.register1.vo.StudentVO;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.time.ZoneOffset;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import static java.lang.System.currentTimeMillis;

@Service
public class RegisterServiceImpl extends ServiceImpl<RegisterMapper, Register> implements RegisterService {

    @Autowired
    RegisterMapper registerMapper;

    @Autowired
    IndexMapper indexMapper;

    @Override
    public PageResult selectByTime(PageDTO pageDTO) {
        PageResult pageResultException = new PageResult();
        if(pageDTO.getStartTime()==null){
            LocalDateTime dateTime = registerMapper.selectMinDate();
            if(dateTime!=null){
                pageDTO.setStartTime(dateTime.toLocalDate());
            }else {
                return pageResultException;
            }
        }
        if(pageDTO.getEndTime()==null){
            LocalDateTime dateTime = registerMapper.selectmaxDate();
            if(dateTime!=null){
                pageDTO.setEndTime(dateTime.toLocalDate().plusDays(1));
            }else {
                return pageResultException;
            }
        }
        List<StudentVO> result= registerMapper.pageQuery(pageDTO);
        List<ArrayList<StudentVO>> individualLists = new ArrayList<>();
        List<StudentVO> eventual = new ArrayList<>();
        for (int j = 0; j < result.size();) {
            StudentVO student = result.get(j);
            String name = student.getName();
            eventual.add(student);
            ArrayList<StudentVO> individualList = new ArrayList<>();
            for (int i = 0; i < result.size();) {
                int size = result.size();
                StudentVO s = result.get(i);
                if(name.equals(s.getName())){
                    individualList.add(s);
                    result.remove(s);
                }
                if(result.size()==size){
                    i++;
                }else {
                    i=0;
                }
            }
            individualLists.add(individualList);

        }

        for (ArrayList<StudentVO> individuallist : individualLists) {
            long totalTime=0;
            StudentVO studentVO= null;

            for (StudentVO s : individuallist){
                studentVO=s;
                long milliseconds = milliseconds(s);
                totalTime+=milliseconds;
            }
            for (StudentVO stu : eventual) {
                if(stu.getName().equals(studentVO.getName()) ){
                    stu.setTime(String.valueOf(totalTime));
//                    setTime(totalTime-28800000, stu);
                    break;
                }
            }
        }
        LocalDate startTime = pageDTO.getStartTime();
        LocalDate endTime = pageDTO.getEndTime();
        LocalDate dateFirst = registerMapper.selectMinDate().toLocalDate();
        LocalDate dateEnd = registerMapper.selectmaxDate().toLocalDate().plusDays(1);
        List<BookIndex> allBook = indexMapper.selectAll();
        for (int i = 0; i < eventual.size(); i++) {
            StudentVO stu = eventual.get(i);
            Integer chaps = 0;
            for (BookIndex book : allBook) {
                String stuName = stu.getName();
                Integer chap = indexMapper.selectMaxChapter(stuName,book,startTime,endTime);
                if(chap!=null&&chap != 0){
                    Integer count = indexMapper.selectMax(stuName,book,startTime,endTime);
                    if(count>1){
                        chaps+= chap - book.getStartId();
                    }
                }
            }

            Integer inch = 0;
            LocalDateTime firstTime = registerMapper.selectFirstDate(stu.getName());
            if(firstTime!=null){
                 inch = registerMapper.selectIdChapter(stu.getName(),firstTime);
                for (int j = 0; j < allBook.size(); j++) {
                    Integer startId = allBook.get(j).getStartId();
                    Integer endId = allBook.get(j).getEndId();
                    if(inch>=startId && inch<=endId){
                        inch = inch-startId;
                        break;
                    }
                }
            }

            Integer beginChapter_ = registerMapper.selectBeginChapter(stu.getName(),startTime);
            int beginChapter=0;
            if(beginChapter_!=null){
                beginChapter = beginChapter_;
            }
            Integer endChapter_ = registerMapper.selectEndChapter(stu.getName(),startTime,endTime.plusDays(1));
            int endChapter=0;
            if(endChapter_!=null){
                endChapter = endChapter_;
            }

            Integer c = registerMapper.selectMinChapter(stu.getName(),dateFirst,dateEnd);
            String name = registerMapper.selectChapterName(c);
            Integer initChapter = registerMapper.selectClosedChapter(name);
            Integer chapters = chaps-inch;
            if(beginChapter==endChapter){
                stu.setAddChapter(String.valueOf(beginChapter));
            }else {
                stu.setAddChapter(String.valueOf(chapters));
            }
            String eChapters_ = stu.getAddChapter();
            long eChapters = Integer.parseInt(eChapters_);

//            double times_ = milliseconds(stu);
            String times_ = stu.getTime();
            double times = Double.parseDouble(times_)/1000/60/60;
            double efficiency_= eChapters/times;
            setTime(Integer.parseInt(times_),stu);
            if(times==0){
                stu.setEfficiency("0");
            }else {
                String str = String.format("%.3f", efficiency_);
                double res = Double.parseDouble(str);
                String efficiency = String.valueOf(res);
                stu.setEfficiency(efficiency);
            }
            LocalDateTime dateTime = registerMapper.selectMaxDate(stu.getName());
            String chapter = registerMapper.selectNowChapter(dateTime,stu.getName());
            String content = registerMapper.selectNowContent(dateTime,stu.getName());
            String day = registerMapper.selectNowDay(dateTime,stu.getName());
            stu.setDay(day);
            stu.setContent(content);
            stu.setChapter(chapter);

        }

        int page = pageDTO.getPage();
        int pagesize = pageDTO.getPageSize();
        int startPage = (page-1)*pagesize;
        int endPage = startPage+pagesize;
        for (int i = 0; i < eventual.size(); i++) {
            for (int j = 0; j < eventual.size()-1-i; j++) {
                if(Double.parseDouble(eventual.get(j).getTime())<Double.parseDouble(eventual.get(j+1).getTime())){
                    StudentVO s1 = eventual.get(j);
                    StudentVO s2 = eventual.get(j+1);
                    eventual.set(j+1,s1);
                    eventual.set(j,s2);
                }
            }
        }

        List<StudentVO> resultList = new ArrayList<>();
        for(int i = startPage;i<endPage&&i<eventual.size();i++){
            resultList.add(eventual.get(i));
        }

        PageResult pageResult = new PageResult(eventual.size(), resultList);
        return pageResult;
    }


    public BooksAndNamesVO selectBooksAndNames() {

        List<NamesVO> classesList = registerMapper.selectAllClasses();
        for (int i = 0; i < classesList.size(); i++) {
            NamesVO oneClass = classesList.get(i);
            String idClass = oneClass.getIdClass();
            String studentClass = oneClass.getStudentClass();
            String[] names = registerMapper.selectAllNames(idClass,studentClass);
            oneClass.setNames(names);
        }

        List<BooksVO> booksList = registerMapper.selectAllChapters();
        for (int i = 0; i < booksList.size(); i++) {
            BooksVO oneBook = booksList.get(i);
            String name = oneBook.getName();
            String chapter = oneBook.getChapter();
            String[] contents = registerMapper.selectAllContent(name,chapter);
            oneBook.setContent(contents);
        }
        BooksAndNamesVO booksAndNamesList = new BooksAndNamesVO(booksList,classesList);
        return booksAndNamesList;
    }


    public Result signOut(String idChapter,String name,String book,String chapter) {
        //查询章节
        Integer id = registerMapper.selectByContent(idChapter,book,chapter);
        try {
            //设置章节
            registerMapper.setIdChapter(name, id);
            //查询该同学未签到的记录
            Register register = registerMapper.selectStu(name, id);
            //获取他的签到时间
            Date startDate = register.getStartDate();
            LocalDate startDate_ = startDate.toInstant().atZone(ZoneId.systemDefault()).toLocalDate();
            long startTimes_ = startDate_.atStartOfDay(ZoneOffset.ofHours(8)).toInstant().toEpochMilli();
            //获取签退时间
            long signOutTime = currentTimeMillis();
            Date endDate = new Date(signOutTime);
            LocalDate endDate_ = endDate.toInstant().atZone(ZoneId.systemDefault()).toLocalDate();
            long endTimes_ = endDate_.atStartOfDay(ZoneOffset.ofHours(8)).toInstant().toEpochMilli();

            if (startTimes_ != endTimes_) {
                long end = startDate.getTime() + 10800000;
                Date date = new Date(end);
                endDate = date;
                LocalDate endDatee = endDate.toInstant().atZone(ZoneId.systemDefault()).toLocalDate();
                long endTimese_ = endDatee.atStartOfDay(ZoneOffset.ofHours(8)).toInstant().toEpochMilli();
                if (endTimese_ > startTimes_) {
                    DateTimeFormatter fmt = DateTimeFormatter.ofPattern("yyyy-MM-dd");
                    String localDateStr = startDate_.format(fmt);
                    String end_ = localDateStr + " 23:00:00";
                    SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
                    try {
                        Date newTime = format.parse(end_);
                        endDate = newTime;
                    } catch (ParseException e) {
                        e.printStackTrace();
                    }
                }
            }
            register.setEndDate(endDate);
            long endTime = endDate.getTime();
            long startTime = startDate.getTime();
            long millisecond = endTime - startTime;
            SimpleDateFormat format = new SimpleDateFormat("HH:mm:ss");
            String format1 = format.format(millisecond-3600000*8);
            register.setTime(format1);
            register.setIsEnd(1);
            register.setIdChapter(id);
            registerMapper.updateStu(register);
            return Result.success("签退成功");
        } catch (Exception e){
            return Result.error("签退失败");
        }
    }


    private static void setTime(long totalTime, StudentVO stu) {
//        SimpleDateFormat format = new SimpleDateFormat("HH:mm:ss");
//        String format1 = format.format(totalTime);
//        stu.setTime(format1);
        double hours = (double) totalTime / 1000 / 60 / 60;
        String str = String.format("%.1f", hours);
        double res = Double.parseDouble(str);
        stu.setTime(String.valueOf(res));
    }

    public static Long milliseconds(StudentVO student) {
        String temp = student.getTime();
        String time ="1970-01-02 "+temp;
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        Date date = null;
        try {
            date = simpleDateFormat.parse(time);
            System.out.println(date);
        } catch (ParseException e) {
            throw new RuntimeException(e);
        }
        long ts = date.getTime();
        long res = ts-57600000;
        return res;
    }
}
